package com.akjava.gwt.bvh.client.poseframe; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.three.client.gwt.boneanimation.AngleAndPosition; import com.akjava.gwt.three.client.gwt.boneanimation.AnimationBonesData; import com.akjava.gwt.three.client.java.utils.GWTThreeUtils; import com.akjava.gwt.three.client.js.THREE; import com.akjava.gwt.three.client.js.math.Matrix4; import com.akjava.gwt.three.client.js.math.Vector3; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONValue; public class PoseEditorData { public static final String KEY_INDEX="DATA_INDEX"; public static final String KEY_DATA="DATA_VALUE"; public static final String KEY_IMAGE="DATA_IMAGE"; public static final String KEY_HEAD="DATA_HEAD"; public String getName() { return name; } public void setName(String name) { this.name = name; } public List<PoseFrameData> getPoseFrameDatas() { return poseFrameDatas; } public void setPoseFrameDatas(List<PoseFrameData> poseFrameDatas) { this.poseFrameDatas = poseFrameDatas; } public List<String> getBones() { return bones; } public void setBones(List<String> bones) { this.bones = bones; } public double getCdate() { return cdate; } public void setCdate(double cdate) { this.cdate = cdate; } private String name; private List<PoseFrameData> poseFrameDatas; private List<String> bones; private double cdate; private int fileId=-1; public int getFileId() { return fileId; } public void setFileId(int fileId) { this.fileId = fileId; } private boolean modified; public boolean isModified() { return modified; } public void setModified(boolean modified) { this.modified = modified; } /* * just need boneIndex & bone Position * */ public void updateMatrix(AnimationBonesData abData){ for(PoseFrameData fdata:poseFrameDatas){ List<AngleAndPosition> apList=new ArrayList<AngleAndPosition>(); fdata.setAngleAndMatrixs(apList); for(int i=0;i<fdata.getAngles().size();i++){ Vector3 anglePos=fdata.getAngles().get(i).clone(); Vector3 posRef=fdata.getPositions().get(i).clone(); if(i>=bones.size()){ LogUtils.log("invalid pose for bone"); return; } int index=abData.getBoneIndex(bones.get(i)); if(index!=-1){//has bone Vector3 bonePos=abData.getBaseBoneRelativePosition(index); posRef.addSelf(bonePos); }else{ LogUtils.log("not-has:"+bones.get(i)); } Vector3 vector=GWTThreeUtils.degreeToRagiant(anglePos); Matrix4 mx=THREE.Matrix4().makeRotationFromEuler(THREE.Euler(vector.getX(),vector.getY(),vector.getZ(), "XYZ")); mx.setPosition(posRef); AngleAndPosition ap=new AngleAndPosition(anglePos, posRef, mx); fdata.getAngleAndMatrixs().add(ap); } } } public static JSONObject convertToJson(PoseEditorData data){ JSONObject poseData=new JSONObject(); //name poseData.put("name", new JSONString(data.getName())); poseData.put("cdate", new JSONNumber(data.getCdate())); //LogUtils.log("name-cdate"); //bones JSONArray bones=new JSONArray(); for(int i=0;i<data.getBones().size();i++){ bones.set(i, new JSONString(data.getBones().get(i))); } poseData.put("bones", bones); JSONArray frames=new JSONArray(); for(int i=0;i<data.getPoseFrameDatas().size();i++){ JSONObject frameValue=new JSONObject(); PoseFrameData fdata=data.getPoseFrameDatas().get(i); //angles List<Vector3> angles=fdata.getAngles(); if(angles==null){ LogUtils.log("warn:angles is null"); } JSONArray anglesValue=new JSONArray(); for(int j=0;j<angles.size();j++){ anglesValue.set(j, toJSONArray(angles.get(j))); } frameValue.put("angles", anglesValue); //LogUtils.log("angles"); //positions List<Vector3> positions=fdata.getPositions(); JSONArray positionValue=new JSONArray(); for(int j=0;j<positions.size();j++){ positionValue.set(j, toJSONArray(positions.get(j))); } frameValue.put("positions", positionValue); //LogUtils.log("positions"); /* List<String> ikNames=fdata.getIkTargetNames(); JSONArray ikNameValue=new JSONArray(); for(int j=0;j<ikNames.size();j++){ ikNameValue.set(j, new JSONString(ikNames.get(j))); } frameValue.put("ik-names", ikNameValue); //LogUtils.log("ik-names"); * */ //positions /*//no more need ik value Map<String,Vector3> ikpositions=fdata.getIkTargetPositionMap(); JSONArray ikpositionsValue=new JSONArray(); int index=0; for(String name:ikpositions.keySet()){ JSONString jsonName=new JSONString(name); JSONArray jsonvec=toJSONArray(ikpositions.get(name)); JSONObject ikData=new JSONObject(); ikData.put("name", jsonName); ikData.put("pos", jsonvec); ikpositionsValue.set(index,ikData ); index++; } frameValue.put("ik-positions", ikpositionsValue); */ //LogUtils.log("ik-positions"); frames.set(i, frameValue); } poseData.put("frames", frames); return poseData; } private static JSONArray toJSONArray(Vector3 vec){ JSONArray nums=new JSONArray(); nums.set(0, new JSONNumber(vec.getX())); nums.set(1, new JSONNumber(vec.getY())); nums.set(2, new JSONNumber(vec.getZ())); return nums; } //TODO check public static PoseEditorData readData(String jsonString){ JSONValue value=JSONParser.parseStrict(jsonString); //LogUtils.log(value.toString()); JSONObject poseData=value.isObject(); if(poseData==null){ LogUtils.log("invalid-data"); return null; } PoseEditorData data=new PoseEditorData(); JSONValue nameValue=poseData.get("name"); JSONString name=nameValue.isString(); if(name==null){ LogUtils.log("invalid-name"); return null; } data.setName(name.stringValue()); // LogUtils.log(data.getName()); JSONValue cdateValue=poseData.get("cdate"); JSONNumber cdate=cdateValue.isNumber(); if(cdate==null){ LogUtils.log("invalid-cdate"); return null; } data.setCdate(cdate.doubleValue()); //LogUtils.log(""+data.getCdate()); //bone-names JSONArray boneNames=poseData.get("bones").isArray(); if(boneNames==null){ LogUtils.log("invalid-bones"); return null; } List<String> bones=new ArrayList<String>(); int bs=boneNames.size(); for(int i=0;i<bs;i++){ JSONValue js=boneNames.get(i); JSONString jsn=js.isString(); if(jsn!=null){ bones.add(jsn.stringValue()); }else{ LogUtils.log("invalid-bones-name:"+i); } } data.setBones(bones); JSONArray frames=poseData.get("frames").isArray(); if(frames==null){ LogUtils.log("invalid-frames"); return null; } List<PoseFrameData> frameDatas=new ArrayList<PoseFrameData>(); int fs=frames.size(); for(int i=0;i<fs;i++){ PoseFrameData frameData=new PoseFrameData(); JSONValue js=frames.get(i); JSONObject jsn=js.isObject(); if(jsn!=null){ //angle List<Vector3> angles=readAngles(jsn.get("angles")); if(angles==null){ LogUtils.log("invalid-frames-angle:"+i); return null; } frameData.setAngles(angles); List<Vector3> positions=readPositions(jsn.get("positions")); if(positions==null){ LogUtils.log("invalid-frames-positions:"+i); return null; } frameData.setPositions(positions); /* List<String> nameList=readIkNames(jsn.get("ik-names")); if(nameList==null){ LogUtils.log("invalid-frames-nameList:"+i); return null; } frameData.setIkTargetNames(nameList); */ /* Map<String,Vector3> ikPositions=readIkPositions(jsn.get("ik-positions"));//old format if(ikPositions==null){ LogUtils.log("invalid-frames-ikPositions:"+i); return null; } frameData.setIkTargetPositionMap(ikPositions); */ }else{ LogUtils.log("invalid-frames:"+i); return null; } frameDatas.add(frameData); } data.setPoseFrameDatas(frameDatas); //frames //angle //position -->AngleAndMatrix relate-path of bone //ikdata return data; } private static List<Vector3> readAngles(JSONValue value){ if(value==null){ return null; } List<Vector3> angles=new ArrayList<Vector3>(); JSONArray anglesArray=value.isArray(); if(anglesArray!=null){ int as=anglesArray.size(); for(int j=0;j<as;j++){ JSONValue angleV=anglesArray.get(j); JSONArray angle=angleV.isArray(); if(angle==null){ LogUtils.log("invalid-frames-angle:"); return null; } if(angle.size()==3){ Vector3 angleVec=THREE.Vector3(); JSONNumber xv=angle.get(0).isNumber(); JSONNumber yv=angle.get(1).isNumber(); JSONNumber zv=angle.get(2).isNumber(); if(xv!=null && yv!=null &&zv!=null){ angleVec.set(xv.doubleValue(), yv.doubleValue(), zv.doubleValue()); angles.add(angleVec); }else{ LogUtils.log("invalid-frames-angle-v:"); return null; } }else{ LogUtils.log("invalid-frames-angle-size:"); return null; } } }else{ LogUtils.log("invalid-frames-angles:"); return null; } return angles; } private static List<Vector3> readPositions(JSONValue value){ if(value==null){ return null; } List<Vector3> positions=new ArrayList<Vector3>(); JSONArray positionsArray=value.isArray(); if(positionsArray!=null){ int as=positionsArray.size(); for(int j=0;j<as;j++){ JSONValue positionV=positionsArray.get(j); JSONArray position=positionV.isArray(); if(position==null){ return null; } if(position.size()==3){ Vector3 positionVec=THREE.Vector3(); JSONNumber xv=position.get(0).isNumber(); JSONNumber yv=position.get(1).isNumber(); JSONNumber zv=position.get(2).isNumber(); if(xv!=null && yv!=null &&zv!=null){ positionVec.set(xv.doubleValue(), yv.doubleValue(), zv.doubleValue()); positions.add(positionVec); }else{ return null; } }else{ return null; } } }else{ return null; } return positions; } private static String[] oldIkNames={"LowerBack-Neck1","RightArm-RightForeArm","RightUpLeg-RightLeg","LeftArm-LeftForeArm","LeftUpLeg-LeftLeg"}; /** * @deprecated no more ik use * @param value * @return */ private static Map<String,Vector3> readIkPositions(JSONValue value){ if(value==null){ return null; } Map<String,Vector3> ikpositions=new LinkedHashMap<String,Vector3>(); //ik-positions JSONArray ikpositionsArray=value.isArray(); if(ikpositionsArray!=null){ int iks=ikpositionsArray.size(); for(int j=0;j<iks;j++){ JSONValue positionV=ikpositionsArray.get(j); JSONArray position=positionV.isArray(); if(position==null){ //LogUtils.log("read as New"); JSONObject jsonData=positionV.isObject(); if(jsonData==null){ LogUtils.log("xx:"+ikpositionsArray.get(j).toString()); return null; } //LogUtils.log(jsonData.getJavaScriptObject()); JSONValue jsonName=jsonData.get("name"); JSONString name=jsonName.isString(); if(name==null){ return null; } JSONValue jsonPos=jsonData.get("pos"); JSONArray jsonvec=jsonPos.isArray(); if(jsonvec==null){ return null; } //convert to vector Vector3 positionVec=THREE.Vector3(); JSONNumber xv=jsonvec.get(0).isNumber(); JSONNumber yv=jsonvec.get(1).isNumber(); JSONNumber zv=jsonvec.get(2).isNumber(); if(xv!=null && yv!=null &&zv!=null){ positionVec.set(xv.doubleValue(), yv.doubleValue(), zv.doubleValue()); ikpositions.put(name.stringValue(),positionVec); }else{ return null; } }else{ LogUtils.log("read as old"); //for old version if(position.size()==3){ Vector3 positionVec=THREE.Vector3(); JSONNumber xv=position.get(0).isNumber(); JSONNumber yv=position.get(1).isNumber(); JSONNumber zv=position.get(2).isNumber(); if(xv!=null && yv!=null &&zv!=null){ positionVec.set(xv.doubleValue(), yv.doubleValue(), zv.doubleValue()); ikpositions.put(oldIkNames[j],positionVec); }else{ return null; } }else{ return null; } } } } return ikpositions; } private static List<String> readIkNames(JSONValue value){ if(value==null){ return null; } List<String> names=new ArrayList<String>(); JSONArray ikNamesArray=value.isArray(); if(ikNamesArray==null){ //LogUtils.log("invalid-framesposition:"+i); return null; } for(int j=0;j<ikNamesArray.size();j++){ JSONValue ikn=ikNamesArray.get(j); JSONString iknv=ikn.isString(); if(iknv!=null){ names.add(iknv.stringValue()); }else{ //LogUtils.log("invalid-frames-targetname:"+i+","+j); return null; } } return names; } }